package com.behome.netty.common;

import io.netty.util.internal.StringUtil;
import org.apache.commons.lang3.StringUtils;

import java.nio.ByteBuffer;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

public class ByteConventerKit {
    public ByteConventerKit() {
    }

    public static byte[] intToBytes2(int value) {
        byte[] src = new byte[]{(byte)(value >> 24 & 255), (byte)(value >> 16 & 255), (byte)(value >> 8 & 255), (byte)(value & 255)};
        return src;
    }

    public static int bytesToInt2(byte[] src, int offset) {
        if(src.length < 4) {
            throw new NumberFormatException("src长度不足4个字节,不能转换为int型");
        } else {
            int value = (src[offset] & 255) << 24 | (src[offset + 1] & 255) << 16 | (src[offset + 2] & 255) << 8 | src[offset + 3] & 255;
            return value;
        }
    }

    public static String bcdToStr(byte[] bytes) {
        StringBuffer temp = new StringBuffer(bytes.length * 2);

        for(int i = 0; i < bytes.length; ++i) {
            temp.append(Integer.toHexString((bytes[i] & 240) >>> 4).toUpperCase());
            temp.append(Integer.toHexString(bytes[i] & 15).toUpperCase());
        }

        return temp.toString();
    }

    public static byte[] strToBcd(String asc) {
        int len = asc.length();
        int mod = len % 2;
        if(mod != 0) {
            asc = "0" + asc;
            len = asc.length();
        }

        byte[] abt = new byte[len];
        if(len >= 2) {
            len /= 2;
        }

        byte[] bbt = new byte[len];
        abt = asc.getBytes();

        for(int p = 0; p < asc.length() / 2; ++p) {
            int j;
            if(abt[2 * p] >= 48 && abt[2 * p] <= 57) {
                j = abt[2 * p] - 48;
            } else if(abt[2 * p] >= 97 && abt[2 * p] <= 122) {
                j = abt[2 * p] - 97 + 10;
            } else {
                j = abt[2 * p] - 65 + 10;
            }

            int k;
            if(abt[2 * p + 1] >= 48 && abt[2 * p + 1] <= 57) {
                k = abt[2 * p + 1] - 48;
            } else if(abt[2 * p + 1] >= 97 && abt[2 * p + 1] <= 122) {
                k = abt[2 * p + 1] - 97 + 10;
            } else {
                k = abt[2 * p + 1] - 65 + 10;
            }

            int a = (j << 4) + k;
            byte b = (byte)a;
            bbt[p] = b;
        }

        return bbt;
    }

    public static byte[] shortToBytes(short s) {
        byte[] targets = new byte[2];

        for(int i = 0; i < 2; ++i) {
            int offset = (targets.length - 1 - i) * 8;
            targets[i] = (byte)(s >>> offset & 255);
        }

        return targets;
    }

    public static short bytesToShort(byte[] res) {
        int ret = 0;
        if(res != null && res.length > 0) {
            ret = res[0] * 256 + (res[1] & 255);
        }

        return (short)ret;
    }

    public static String byteToHexStr(byte b, boolean left0, boolean isContains0x) {
        int i = b & 255;
        String tmpValue = Integer.toHexString(i).toUpperCase();
        if(left0 && tmpValue.length() == 1) {
            tmpValue = "0" + tmpValue;
        }

        return isContains0x?"0x" + tmpValue:tmpValue;
    }

    public static byte hexStrToByte(String hex) {
        String tmp = hex;
        if(hex.startsWith("0x") || hex.startsWith("0X")) {
            tmp = hex.substring(2);
        }

        return Integer.valueOf(tmp, 16).byteValue();
    }

    public static String bytesToHexStr(byte[] buffer, boolean isContains0x) {
        return buffer != null && buffer.length > 0?bytesToHexStr(buffer, isContains0x, false):"";
    }

    public static String bytesToHexStr(byte[] buffer, boolean isContains0x, boolean isSplitWithWhiteSpace) {
        if(buffer != null && buffer.length > 0) {
            StringBuilder ret = new StringBuilder();
            for (byte b : buffer) {
                ret.append(byteToHexStr(b, true, isContains0x)).append(isSplitWithWhiteSpace ? " " : "");
            }
            return ret.toString().trim();
        } else {
            return "";
        }
    }

    public static String bytesToThinHexStr(byte[] buffer) {
        String ret = "";
        byte[] var2 = buffer;
        int var3 = buffer.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            byte b = var2[var4];
            ret = ret + byteToHexStr(b, false, false);
        }

        return ret.trim();
    }

    public static byte[] datetimeToBytes(Date date) {
        if(date == null) {
            return new byte[4];
        } else {
            int time = (int)(date.getTime() / 1000L);
            return intToBytes2(time);
        }
    }

    public static Date bytesToDatetime(byte[] timeBytes) {
        if(timeBytes != null && timeBytes.length == 4) {
            long time = (long)bytesToInt2(timeBytes, 0);
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(time * 1000L);
            return calendar.getTime();
        } else {
            return null;
        }
    }

    public static byte[] macStrToBytes(String macAddr) {
        if(StringUtil.isNullOrEmpty(macAddr)) {
            return null;
        } else if(macAddr.contains("-") && macAddr.split("-").length == 6) {
            String[] hexStrs = macAddr.split("-");
            byte[] ret = new byte[6];

            for(int i = 0; i < hexStrs.length; ++i) {
                ret[i] = Integer.valueOf(hexStrs[i], 16).byteValue();
            }

            return ret;
        } else if(macAddr.contains("-") && macAddr.split("-").length == 8) {
            String[] hexStrs = macAddr.split("-");
            byte[] ret = new byte[8];

            for (int i = 0; i < hexStrs.length; ++i) {
                ret[i] = Integer.valueOf(hexStrs[i], 16).byteValue();
            }

            return ret;
        } else if(macAddr.length() == 12){
            byte[] ret = new byte[6];
            for(int i = 0; i < ret.length; ++i) {
                String hexStr = macAddr.substring(2 * i, 2 * i + 2);
                ret[i] = Integer.valueOf(hexStr, 16).byteValue();
            }
            return ret;
        } else if(macAddr.length() == 16){
            byte[] ret = new byte[8];
            for(int i = 0; i < ret.length; ++i) {
                String hexStr = macAddr.substring(2 * i, 2 * i + 2);
                ret[i] = Integer.valueOf(hexStr, 16).byteValue();
            }
            return ret;
        } else if(macAddr.length() == 24){
            byte[] ret = new byte[12];
            for(int i = 0; i < ret.length; ++i) {
                String hexStr = macAddr.substring(2 * i, 2 * i + 2);
                ret[i] = Integer.valueOf(hexStr, 16).byteValue();
            }
            return ret;
        } else{
            return null;
        }
    }

    public static String bytesToMacStr(byte[] macData, boolean containsSplit) {
        if(macData != null) {
            String ret = "";

            for(int i = 0; i < macData.length; ++i) {
                ret = ret + byteToHexStr(macData[i], true, false) + (containsSplit?"-":"");
            }

            if(ret.endsWith("-")) {
                ret = ret.substring(0, ret.length() - 1);
            }

            return ret;
        } else {
            return null;
        }
    }

    public static String bytesToIpStr(byte[] ipData) {
        if(ipData != null && ipData.length == 4) {
            StringBuffer strBuffer = new StringBuffer();

            for(int i = 0; i < ipData.length; ++i) {
                strBuffer.append(byteToUnsignedInt(ipData[i]));
                if(i != 3) {
                    strBuffer.append(".");
                }
            }

            return strBuffer.toString();
        } else {
            return null;
        }
    }

    public static String bytesToIpAndPortStr(byte[] ipAndPortData) {
        if(ipAndPortData != null && ipAndPortData.length == 6) {
            StringBuffer strBuffer = new StringBuffer();

            for(int i = 0; i < ipAndPortData.length - 2; ++i) {
                strBuffer.append(byteToUnsignedInt(ipAndPortData[i]));
                if(i == 3) {
                    strBuffer.append(":");
                } else {
                    strBuffer.append(".");
                }
            }

            byte[] ports = new byte[]{ipAndPortData[4], ipAndPortData[5]};
            int port = shortToUnsignedInt(bytesToShort(ports));
            strBuffer.append(port);
            return strBuffer.toString();
        } else {
            return null;
        }
    }

    public static byte[] ipAndPortStrToBytes(String ipAndPort) {
        if(StringUtils.isNotEmpty(ipAndPort) && ipAndPort.contains(":")) {
            byte[] ipdata = ipStrBytes(ipAndPort.split(":")[0]);
            byte[] portdata = shortToBytes((new Short(ipAndPort.split(":")[1])).shortValue());
            byte[] ret = new byte[6];
            System.arraycopy(ipdata, 0, ret, 0, ipdata.length);
            System.arraycopy(portdata, 0, ret, 4, portdata.length);
            return ret;
        } else {
            return null;
        }
    }

    public static byte[] ipStrBytes(String ip) {
        String[] items = RegularKit.getMatcherValue("^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$", ip);
        ByteBuffer byteBuffer = ByteBuffer.allocate(4);
        String[] var3 = items;
        int var4 = items.length;
        for(int var5 = 0; var5 < var4; ++var5) {
            String str = var3[var5];
            byteBuffer.put((new Short(str)).byteValue());
        }
        return byteBuffer.array();
    }

    public static int byteToUnsignedInt(byte data) {
        return data & 255;
    }

    public static int shortToUnsignedInt(short data) {
        return data & '\uffff';
    }

    public static byte[] hexStrWithWhiteSpaceTobytes(String hexStr) {
//        String s1 = hexStr.replaceAll(" ", "");
//        String regex = "(.{2})";
//        hexStr = hexStr.replaceAll(regex, "$1 ");
        if(!StringUtil.isNullOrEmpty(hexStr) && hexStr.contains(" ")) {
            String[] hexs = hexStr.split(" ");
            byte[] ret = new byte[hexs.length];

            for(int i = 0; i < hexs.length; ++i) {
                ret[i] = hexStrToByte(hexs[i]);
            }
            return ret;
        } else {
            return null;
        }
    }

    public static byte[] hexStrTobytes(String hexStr) {
        if(StringUtil.isNullOrEmpty(hexStr)) {
            return null;
        } else {
            hexStr = hexStr.replaceAll(" ", "");
            byte[] ret = new byte[hexStr.length()];

            for(int i = 0; i < hexStr.length(); ++i) {
                ret[i] = hexStrToByte(hexStr.substring(i, i + 1));
            }

            return ret;
        }
    }

    public static byte[] hexStrTobytes2(String hexStr) {
        if(StringUtil.isNullOrEmpty(hexStr)) {
            return null;
        } else {
            byte[] ret = null;
            if(hexStr.length() % 2 == 0) {
                ret = new byte[hexStr.length() / 2];
            } else {
                ret = new byte[hexStr.length() / 2 + 1];
            }

            for(int i = 0; i < ret.length; ++i) {
                ret[i] = hexStrToByte(hexStr.substring(2 * i, 2 * i + 2));
            }

            return ret;
        }
    }

    public static byte[] serializeEbmId(String ebmID) {
        if(StringUtil.isNullOrEmpty(ebmID)) {
            return null;
        } else {
            if(ebmID.length() == 35) {
                ebmID = "F" + ebmID;
            }

            if(ebmID.length() == 36) {
                return strToBcd(ebmID);
            } else {
                throw new IllegalArgumentException("ebmID值" + ebmID + "非法.");
            }
        }
    }

    public static String deserializeEbmId(byte[] ebmIDBytes) {
        if(ebmIDBytes != null && ebmIDBytes.length == 18) {
            String tmpStr = bcdToStr(ebmIDBytes);
            return tmpStr;
        } else {
            throw new IllegalArgumentException("ebmID值[" + bytesToHexStr(ebmIDBytes, false) + "]非法,ebmID只能为18字节的字节数组.");
        }
    }

    public static byte[] serializeResourceCode(String resourceCode) {
        if(StringUtil.isNullOrEmpty(resourceCode)) {
            return null;
        } else {
            if(resourceCode.length() == 23) {
                resourceCode = "F" + resourceCode;
            }

            if(resourceCode.length() == 24) {
                return strToBcd(resourceCode);
            } else {
                throw new IllegalArgumentException("resourceCode值" + resourceCode + "非法.");
            }
        }
    }

    public static String deserializeResourceCode(byte[] resourceCodeData) {
        if(resourceCodeData.length != 12) {
            throw new IllegalArgumentException("资源编码必须为12个字节的数组.字节数组[" + bytesToHexStr(resourceCodeData, false) + "]不能转换为资源编码.");
        } else {
            String resourceCode = bcdToStr(resourceCodeData);
            if(resourceCode.startsWith("15")) {
                resourceCode = "F" + resourceCode.substring("15".length());
            }

            return resourceCode;
        }
    }

    public static byte[] mergeBytesList(List<byte[]> bytesList) {
        if(bytesList != null && bytesList.size() > 0) {
            int bodyLength = 0;

            byte[] bs;
            for(Iterator var2 = bytesList.iterator(); var2.hasNext(); bodyLength += bs.length) {
                bs = (byte[])var2.next();
            }

            ByteBuffer byteBuffer = ByteBuffer.allocate(bodyLength);
            Iterator var6 = bytesList.iterator();

            while(var6.hasNext()) {
                bs = (byte[])var6.next();
                byteBuffer.put(bs);
            }

            return byteBuffer.array();
        } else {
            return new byte[0];
        }
    }

    public static byte[] mergeBytesList(List<byte[]> bytesList, int mergeTotalLength) {
        if(bytesList != null && bytesList.size() > 0) {
            ByteBuffer byteBuffer = ByteBuffer.allocate(mergeTotalLength);
            Iterator var3 = bytesList.iterator();

            while(var3.hasNext()) {
                byte[] bs = (byte[])var3.next();
                byteBuffer.put(bs);
            }

            return byteBuffer.array();
        } else {
            return new byte[0];
        }
    }
    /**
     * 字节转十六进制
     * @param b 需要进行转换的byte字节
     * @return  转换后的Hex字符串
     */
    public static String byteToHex(byte b){
        String hex = Integer.toHexString(b & 0xFF);
        if(hex.length() < 2){
            hex = "0" + hex;
        }
        return hex;
    }

    /**
     * 将整数转换为byte数组并指定长度
     */
    public static byte[] intToBytesNew(int a, int length) {
        byte[] bs = new byte[length];
        for (int i = bs.length - 1; i >= 0; i--) {
            bs[i] = (byte) (a % 0xFF);
            a = a / 0xFF;
        }
        return bs;
    }

    /**
     * 将byte数组转换为整数
     */
    public static int bytesToIntNew(byte[] src, int offset) {
        if(src.length <3) {
            throw new NumberFormatException("src长度不足3个字节,不能转换为int型");
        } else {
            int value = (src[offset] & 255) << 16 | (src[offset + 1] & 255) << 8 | src[offset + 2] & 255;
            return value;
        }
    }
    /**
     * FM扫描频点列表解析 频点数1B+{频点序号1b,优先级1b,频率3b....}
     *
     * @return java.lang.String
     * @author Ljy
     * @date 2021/3/9 17:23
     */
    public static String to_FmScanFrelist(String fmList) {
        int num = 0;
        StringBuilder sum = new StringBuilder();
        String frepointnum;// 频点序号
        String priority;// 优先级
        String frequency;// 频率
        if (!"00".equals(fmList.substring(0, 2))) {
            int frenum = Integer.parseInt(fmList.substring(0, 2), 16);
            num += 2;
            for (int i = 1; i <= frenum; i++) {
                if(i!=1){
                    sum.append("|");
                }
                frepointnum = fmList.substring(num, num + 2);
                int frepointnums = Integer.parseInt(frepointnum, 16);
                num += 2;
                priority = fmList.substring(num, num + 2);
                int prioritys = Integer.parseInt(priority, 16);
                num += 2;
                frequency = fmList.substring(num, num + 6);
                int frequencys = Integer.parseInt(frequency);
//				Integer integer = Integer.parseInt(frequency.substring(0,4));   跟实际对接设备确认解析方式是否按照BCD编码解析
//				String decimal =String.format("%02d", Integer.parseInt(frequency.substring(5)));
                num += 6;
                sum.append(frepointnums).append(",").append(prioritys).append(",").append(frequencys);
//				sum += frepointnums.toString()+","+prioritys.toString()+","+integer.toString()+"."+decimal+"|";
            }
        } else {
            sum = new StringBuilder("00");
        }
        return sum.toString();
    }
}
